from PyQt6.QtWidgets import (
    QFrame,
    QVBoxLayout,
    QHBoxLayout,
    QLabel,
    QPushButton,
    QTableWidget,
    QTableWidgetItem,
    QHeaderView,
    QComboBox,
)
from PyQt6.QtCore import Qt, pyqtSignal
from datetime import datetime
from http_client import http_client
from utils.style_manager import StyleManager
from database import db_manager
import threading
from typing import Dict, Any, List
import time

class BatchPage(QFrame):
    # 在子线程中更新行状态的信号：传递行号与更新字段
    task_row_update = pyqtSignal(int, dict)
    # 子线程结束时通知主线程弹窗与收尾：success, total, stopped
    task_finished = pyqtSignal(int, int, bool)
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setup_ui()
        # 连接信号
        self.task_row_update.connect(self._on_task_row_update)
        self.task_finished.connect(self._on_task_finished)
        
    def setup_ui(self):
        """设置批量拉群页面UI"""
        page_layout = QVBoxLayout(self)
        page_layout.setSpacing(10)
        page_layout.setContentsMargins(15, 15, 15, 15)  # 增加边距
        
        # 账号选择区域（单行：账号A、账号B、开始按钮）
        account_frame = QFrame()
        account_frame.setMinimumWidth(300)
        account_layout = QHBoxLayout(account_frame)
        account_layout.setSpacing(10)
        account_layout.setContentsMargins(15, 15, 80, 15)

        self.account1_label = QLabel("账号A:")
        account_layout.addWidget(self.account1_label)
        self.account1_combo = QComboBox()
        account_layout.addWidget(self.account1_combo)

        self.account2_label = QLabel("账号B:")
        account_layout.addWidget(self.account2_label)
        self.account2_combo = QComboBox()
        account_layout.addWidget(self.account2_combo)

        account_layout.addStretch();

        self.start_btn = QPushButton("开始")
        self.start_btn.setFixedSize(120, 36)
        self.start_btn.clicked.connect(self.on_group_batch_pull)
        StyleManager.set_button_style(self.start_btn, "success")
        account_layout.addWidget(self.start_btn)

        # 连接选择变化信号
        self.account1_combo.currentIndexChanged.connect(self.on_account_selection_changed)
        self.account2_combo.currentIndexChanged.connect(self.on_account_selection_changed)
        
        page_layout.addWidget(account_frame)
        
        # 表格区域 - 美化表格样式
        self.main_table = QTableWidget()
        self.main_table.setColumnCount(9)
        self.main_table.setHorizontalHeaderLabels([
            "", "No", "账号", "执行", "进度", "明细", "重复率", "状态", "操作"
        ])
        # 统一表格交互与样式
        self.main_table.setEditTriggers(QTableWidget.EditTrigger.NoEditTriggers)
        self.main_table.setSelectionBehavior(QTableWidget.SelectionBehavior.SelectRows)
        self.main_table.setSelectionMode(QTableWidget.SelectionMode.SingleSelection)
        self.main_table.verticalHeader().setDefaultSectionSize(40)
        self.main_table.verticalHeader().setMinimumSectionSize(35)
        StyleManager.set_table_widget_style(self.main_table, "task-table")
        
        # 设置表格撑满容器
        self.main_table.horizontalHeader().setStretchLastSection(True)
        self.main_table.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.ResizeToContents)
        
        # 隐藏垂直表头
        self.main_table.verticalHeader().setVisible(False)
        
        # 设置表格样式
        self.main_table.setAlternatingRowColors(True)
        self.main_table.setRowCount(0)  # 空白表格
        
        page_layout.addWidget(self.main_table)
        
        # 初始化时刷新账号列表
        self.refresh_account_list()
        # 运行状态
        self._stop_requested = False
        self._worker_thread = None
        self._tasks: List[Dict[str, Any]] = []

    def _init_main_table_with_tasks(self, tasks: List[Dict[str, Any]]):
        """根据任务列表初始化主表格"""
        self.main_table.setRowCount(len(tasks))
        for idx, t in enumerate(tasks):
            # No
            self.main_table.setItem(idx, 1, QTableWidgetItem(str(idx + 1)))
            # 账号（所有者）
            self.main_table.setItem(idx, 2, QTableWidgetItem(t.get('owner', '')))
            # 执行（目标）
            self.main_table.setItem(idx, 3, QTableWidgetItem(t.get('target', '')))
            # 进度
            self.main_table.setItem(idx, 4, QTableWidgetItem("待执行"))
            # 明细（群名）
            self.main_table.setItem(idx, 5, QTableWidgetItem(t.get('group_name', '')))
            # 重复率（占位）
            self.main_table.setItem(idx, 6, QTableWidgetItem("-"))
            # 状态
            self.main_table.setItem(idx, 7, QTableWidgetItem("排队中"))
            # 操作
            self.main_table.setItem(idx, 8, QTableWidgetItem("-"))

    def _on_task_row_update(self, row: int, update: Dict[str, Any]):
        """主线程中更新某一行的显示"""
        if row < 0 or row >= self.main_table.rowCount():
            return
        if 'progress' in update:
            self.main_table.setItem(row, 4, QTableWidgetItem(str(update['progress'])))
        if 'status' in update:
            self.main_table.setItem(row, 7, QTableWidgetItem(str(update['status'])))
        if 'detail' in update:
            self.main_table.setItem(row, 5, QTableWidgetItem(str(update['detail'])))

    def _on_task_finished(self, success: int, total: int, stopped: bool):
        """主线程中展示任务完成提示并收尾"""
        from PyQt6.QtWidgets import QMessageBox
        if stopped:
            QMessageBox.information(self, "已停止", f"任务已停止。成功 {success}/{total}")
        else:
            QMessageBox.information(self, "完成", f"批量拉群完成。成功 {success}/{total}")
        self.start_btn.setEnabled(True)

    def on_account_selection_changed(self):
        """账号选择变化事件处理"""
        # 根据选择状态启用/禁用开始按钮
        account1 = self.account1_combo.currentData()
        account2 = self.account2_combo.currentData()
        is_valid = bool(account1) and bool(account2)
        if is_valid:
            user1 = account1.get("user_name")
            user2 = account2.get("user_name")
            is_valid = bool(user1) and bool(user2) and user1 != user2
        self.start_btn.setEnabled(bool(is_valid))
        # 如果任务在进行，保持开始按钮禁用
        if getattr(self, "_worker_thread", None) and self._worker_thread.is_alive():
            self.start_btn.setEnabled(False)

    def refresh_account_list(self):
        """刷新在线账号列表（参考 MessagePage 的获取方式：db_manager.get_online_accounts）"""
        try:
            # 清空现有列表
            self.account1_combo.clear()
            self.account2_combo.clear()

            # 获取在线账号（从本地数据库）
            online_accounts = db_manager.get_online_accounts()
            if not online_accounts:
                # 如果没有在线账号，显示提示信息
                self.account1_combo.addItem("暂无在线账号")
                self.account2_combo.addItem("暂无在线账号")
                self.start_btn.setEnabled(False)
                return
            
            # 添加在线账号到下拉框
            for account in online_accounts:
                # 优先显示昵称，如果没有昵称则显示用户名
                display_name = account.get('nick_name') or account.get('user_name', '未知账号')
                # 为条目附加完整账号数据，便于后续获取 user_name
                self.account1_combo.addItem(display_name, account)
                self.account2_combo.addItem(display_name, account)
            self.on_account_selection_changed()
            
        except Exception as e:
            print(f"刷新账号列表失败: {e}")
            # 显示错误信息
            self.account1_combo.addItem("加载账号列表失败")
            self.account2_combo.addItem("加载账号列表失败")
    
    def on_group_batch_pull(self):
        """批量拉群按钮点击事件"""
        # 获取当前选中的账号
        account1 = self.account1_combo.currentData()
        account2 = self.account2_combo.currentData()
        
        # 检查是否选择了两个不同的账号
        if not account1 or not account2:
            from PyQt6.QtWidgets import QMessageBox
            QMessageBox.warning(self, "选择限制", "当前没有在线账号可用！")
            return
        
        user1 = account1.get("user_name")
        user2 = account2.get("user_name")
        if not user1 or not user2 or user1 == user2:
            from PyQt6.QtWidgets import QMessageBox
            QMessageBox.warning(self, "选择限制", "请选择两个不同的账号进行互相拉群！")
            return
        
        try:
            # 启动后台线程，分别将 A 邀请 B 进 A 的群、B 邀请 A 进 B 的群
            self._stop_requested = False
            self.start_btn.setEnabled(False)

            groups_a = db_manager.get_user_groups(user1) or []
            groups_b = db_manager.get_user_groups(user2) or []

            if not groups_a and not groups_b:
                from PyQt6.QtWidgets import QMessageBox
                QMessageBox.warning(self, "无可用群聊", "两个账号均无群聊记录，无法执行拉群。")
                self.start_btn.setEnabled(True)
                return

            # 构建任务队列并初始化表格
            tasks: List[Dict[str, Any]] = []
            for g in groups_a:
                tasks.append({
                    'owner': user1,
                    'target': user2,
                    'qid': g.get('qid', ''),
                    'group_name': g.get('group_name', ''),
                })
            for g in groups_b:
                tasks.append({
                    'owner': user2,
                    'target': user1,
                    'qid': g.get('qid', ''),
                    'group_name': g.get('group_name', ''),
                })

            self._tasks = tasks
            self._init_main_table_with_tasks(tasks)

            def _worker():
                total = 0
                success = 0

                for idx, task in enumerate(tasks):
                    if self._stop_requested:
                        break
                    owner_wxid = task['owner']
                    target_wxid = task['target']
                    qid = task.get('qid', '')
                    group_name = task.get('group_name', '')
                    if not qid:
                        continue
                    total += 1
                    # 更新为执行中
                    self.task_row_update.emit(idx, {'progress': '执行中', 'status': '执行中'})
                    try:
                        # 先尝试 40+ 接口
                        resp = http_client.invite_chat_room_member_upper_40(owner_wxid, qid, target_wxid)
                        print("resp", resp)
                        ok = bool(resp.get("Success", False)) and resp.get("Code", -1) == 0
                        if not ok:
                            # 回退 40- 接口
                            resp2 = http_client.invite_chat_room_member_lower_40(owner_wxid, qid, target_wxid)
                            print("resp2", resp2)
                            ok = bool(resp2.get("Success", False)) and resp2.get("Code", -1) == 0
                        if ok:
                            success += 1
                            self.task_row_update.emit(idx, {'progress': '完成', 'status': '成功'})
                        else:
                            self.task_row_update.emit(idx, {'progress': '失败', 'status': '失败'})
                    except Exception:
                        self.task_row_update.emit(idx, {'progress': '错误', 'status': '错误'})

                    # 每次接口调用之间增加 5 秒延时（可被停止中断）
                    if self._stop_requested:
                        break
                    time.sleep(5)

                # 通知主线程展示提示并收尾
                self.task_finished.emit(success, total, self._stop_requested)

            self._worker_thread = threading.Thread(target=_worker, daemon=True)
            self._worker_thread.start()

        except Exception as e:
            from PyQt6.QtWidgets import QMessageBox
            QMessageBox.critical(self, "错误", f"批量拉群出错: {str(e)}") 

    def on_stop_clicked(self):
        """停止批量拉群"""
        self._stop_requested = True